package work.comeback.omo.dao.movie.imp;

import work.comeback.omo.dao.movie.IMovieInfo;
import work.comeback.omo.model.movie.info.MovieVoidData;
import work.comeback.omo.util.configuration.Application;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MovieInfoImpl implements IMovieInfo {
    private static final Application application = Application.getInstance();
    // SQL 常量
    private static final String INSERT_MOVIE_INFO = "INSERT INTO movie_info (vod_id, vod_name, type_name, vod_time, vod_remarks) VALUES (?, ?, ?, ?, ?)";
    private static final String SELECT_MOVIES_BY_NAME = "SELECT vod_id, vod_name, type_name, vod_time, vod_remarks FROM movie_info WHERE vod_name LIKE ?";
    private static final String SELECT_MOVIE_INFO = "SELECT vod_id, vod_name, type_name, vod_time, vod_remarks FROM movie_info WHERE vod_id = ?";
    private static final String DELETE_MOVIE_INFO = "DELETE FROM movie_info WHERE vod_id = ?";
    private static final String UPDATE_MOVIE_INFO = "UPDATE movie_info SET vod_name = ?, type_name = ?, vod_time = ?, vod_remarks = ? WHERE vod_id = ?";
    private static final String SELECT_GROUPED_MOVIE_INFO = "SELECT vod_id, vod_name, type_name, vod_time, vod_remarks FROM movie_info LIMIT ?";
    private static final String SELECT_ALL_TYPE_NAMES = "SELECT DISTINCT type_name FROM movie_info";
    private static final String SELECT_MOVIES_BY_TYPE_NAME = "SELECT vod_id, vod_name, type_name, vod_time, vod_remarks FROM movie_info WHERE type_name = ? LIMIT ?";

    private final Connection connection;

    // 构造方法，接收数据库连接对象
    public MovieInfoImpl() {
        this(application.getConnection());
    }

    public MovieInfoImpl(Connection connection) {
        this.connection = connection;
    }

    // 保存单个电影信息
    @Override
    public boolean save(MovieVoidData data) {
        try (PreparedStatement stmt = connection.prepareStatement(INSERT_MOVIE_INFO)) {
            setMovieInfoParams(stmt, data);
            stmt.executeUpdate();
            return true;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 批量保存电影信息
    @Override
    public boolean saveAll(List<MovieVoidData> dataList) {
        try (PreparedStatement stmt = connection.prepareStatement(INSERT_MOVIE_INFO)) {
            for (MovieVoidData data : dataList) {
                setMovieInfoParams(stmt, data);
                stmt.addBatch();
            }
            stmt.executeBatch();
            return true;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 设置电影信息参数
    private void setMovieInfoParams(PreparedStatement stmt, MovieVoidData data) throws SQLException {
        stmt.setInt(1, data.getVodId());
        stmt.setString(2, data.getVodName());
        stmt.setString(3, data.getTypeName());
        stmt.setString(4, data.getVodTime());
        stmt.setString(5, data.getVodRemarks());
    }

    // 根据 vodId 获取电影信息
    @Override
    public MovieVoidData getMovieInfoById(int vodId) {
        try (PreparedStatement stmt = connection.prepareStatement(SELECT_MOVIE_INFO)) {
            stmt.setInt(1, vodId);
            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {
                return mapRowToMovieInfo(rs);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<MovieVoidData> getMoviesByName(String movieName) {
        List<MovieVoidData> movieList = new ArrayList<>();
        try (PreparedStatement stmt = connection.prepareStatement(SELECT_MOVIES_BY_NAME)) {
            stmt.setString(1, "%" + movieName + "%");
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                movieList.add(mapRowToMovieInfo(rs));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return movieList;
    }

    // 将查询结果映射到 MovieVoidData 对象
    private MovieVoidData mapRowToMovieInfo(ResultSet rs) throws SQLException {
        MovieVoidData movieVoidData = new MovieVoidData();
        movieVoidData.setVodId(rs.getInt("vod_id"));
        movieVoidData.setVodName(rs.getString("vod_name"));
        movieVoidData.setTypeName(rs.getString("type_name"));
        movieVoidData.setVodTime(rs.getString("vod_time"));
        movieVoidData.setVodRemarks(rs.getString("vod_remarks"));
        return movieVoidData;
    }

    // 根据 vodId 删除电影信息
    @Override
    public boolean deleteById(int vodId) {
        try (PreparedStatement stmt = connection.prepareStatement(DELETE_MOVIE_INFO)) {
            stmt.setInt(1, vodId);
            return stmt.executeUpdate() > 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 更新电影信息
    @Override
    public boolean update(MovieVoidData data) {
        try (PreparedStatement stmt = connection.prepareStatement(UPDATE_MOVIE_INFO)) {
            setMovieInfoParams(stmt, data);
            stmt.setInt(5, data.getVodId());  // vodId 是更新条件
            stmt.executeUpdate();
            return true;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 按类型分组查询电影信息
    @Override
    public Map<String, List<MovieVoidData>> getGroupedDataByTypeName(int limit) {
        Map<String, List<MovieVoidData>> groupedData = new HashMap<>();
        try (PreparedStatement stmt = connection.prepareStatement(SELECT_GROUPED_MOVIE_INFO)) {
            stmt.setInt(1, limit);  // 限制返回结果条数
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                MovieVoidData movieVoidData = mapRowToMovieInfo(rs);
                String typeName = movieVoidData.getTypeName();
                groupedData.computeIfAbsent(typeName, k -> new ArrayList<>()).add(movieVoidData);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return groupedData;
    }

    @Override
    public List<String> getAllTypeNames() {
        List<String> typeNames = new ArrayList<>();
        try (PreparedStatement stmt = connection.prepareStatement(SELECT_ALL_TYPE_NAMES)) {
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                typeNames.add(rs.getString("type_name"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return typeNames;
    }

    @Override
    public List<MovieVoidData> getMoviesByTypeName(String typeName, int limit) {
        List<MovieVoidData> movieList = new ArrayList<>();
        try (PreparedStatement stmt = connection.prepareStatement(SELECT_MOVIES_BY_TYPE_NAME)) {
            stmt.setString(1, typeName);
            stmt.setInt(2, limit);
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                movieList.add(mapRowToMovieInfo(rs));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return movieList;
    }
}